home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
526-550
/
disk_540
/
parm
/
parm_src.lzh
/
Run.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-28
|
8KB
|
291 lines
/*
* Run.c - Copyright © 1990 by S.R. & P.C.
*
* Created: 16 Jun 1990
* Modified: 28 Jul 1991 18:36:43
*
* Make>> make
*/
#include "ParMBase.h"
/***** global variables *****/
extern struct ExecBase *SysBase;
extern struct ParMBase *ParMBase;
/* Execute a CLI command as background process */
void ARun(struct ParMConfig *PCfg, struct RunInfo *Command)
{
struct ParMBase *ParMBase;
struct ProcessControlBlock *PCB;
long CLI;
if (!(PCB = AllocMem(sizeof(struct ProcessControlBlock), MEMF_PUBLIC|MEMF_CLEAR)))
return;
PCB->pcb_StackSize = Command->ri_Stack;
PCB->pcb_Pri = Command->ri_Pri;
PCB->pcb_Console.pcb_ConName = Command->ri_Window;
PCB->pcb_Control = (Command->ri_Window) ? PRF_STDIO : PRF_SAVEIO;
if ((CLI = ASyncRun(Command->ri_Cmd, Command->ri_Args, PCB)) <= 0) {
if (CLI == PR_NOSTDIO)
SimpleRequest(PCfg->ReqTitle, "Couldn't open window:\n\"%s\"", Command->ri_Window);
else
SimpleRequest(PCfg->ReqTitle, "Couldn't load \"%s\"\n%s.", Command->ri_Cmd, StrIoErr());
}
FreeMem(PCB, sizeof(struct ProcessControlBlock));
}
/* Execute a CLI command as background or interactive shell */
void Run(struct ParMConfig *PCfg, struct RunInfo *Command, BYTE Mode)
{
struct ParMBase *ParMBase;
struct NewShell *NS;
struct Process *pp;
char *Window, *Cmd;
BPTR fh;
short i=0, err;
char FromFile[32], CmdBuf[128];
if (!(NS = AllocMem(sizeof(struct NewShell), MEMF_PUBLIC|MEMF_CLEAR)))
return;
pp = (struct Process *)SysBase->ThisTask;
NS->nsh_StackSize = Command->ri_Stack;
NS->nsh_Pri = Command->ri_Pri;
NS->nsh_Input = pp->pr_CIS;
NS->nsh_Output = pp->pr_COS;
NS->nsh_Control = BACKGROUND_SHELL;
Cmd = Command->ri_Cmd;
if (Mode == TOK_SHELL) {
for(;;) {
SPrintf(FromFile, "%sParMCmd%d", PCfg->TmpDir, i++);
fh = Open(FromFile, MODE_NEWFILE);
if (fh)
break;
else if ((err = IoErr()) != ERROR_OBJECT_IN_USE || i>32) {
SimpleRequest(PCfg->ReqTitle, "Unable to open script file\n%s.", DosError(err));
FreeMem(NS, sizeof(struct NewShell));
return;
}
}
FPrintf(fh, "%s\nEndCLI >NIL:\n", Cmd);
Close(fh);
if (!(Window = Command->ri_Window))
Window = PCfg->ShellWindow;
SPrintf(CmdBuf, "\"%s\" \"%s\" From %s", PCfg->ShellCmd, Window, FromFile);
Cmd = CmdBuf;
}
ASyncRun(Cmd, NULL, (struct ProcessControlBlock *)NS);
FreeMem(NS, sizeof(struct NewShell));
}
/* procedures to support running WorkBench programs */
/*
* Free up space used by a workbench startup message. Called whenever
* a workbench program replies to the startup message, and whenever
* WBRun() gets an error.
*/
void WBFree(struct Extended_WBStartup *EWBS)
{
struct ParMBase *ParMBase;
register BPTR lock;
register int i;
if (EWBS->WBStartup.sm_ArgList) {
for( i=0 ; i<EWBS->WBStartup.sm_NumArgs ; i++ ) {
if (lock = EWBS->WBStartup.sm_ArgList[i].wa_Lock)
UnLock(lock);
FreeStr(EWBS->WBStartup.sm_ArgList[i].wa_Name);
}
FreeMem(EWBS->ArgArray, EWBS->ArrayLength*sizeof(struct WBArg));
}
if (EWBS->WBStartup.sm_Segment)
UnLoadPrg(EWBS->WBStartup.sm_Segment);
FreeMem(EWBS, sizeof(struct Extended_WBStartup));
}
long MakeWBArg(struct ParMConfig *PCfg, struct WBArg *WBArg, char *Cmd)
{
struct ParMBase *ParMBase;
struct Process *pp;
BPTR DirLock;
char Dir[256], *s, *n;
strcpy(Dir, Cmd);
s = BaseName(Dir);
if (!(n = CopyStr(s)))
return FALSE;
pp = (struct Process *)SysBase->ThisTask;
if (s == Dir)
DirLock = DupLock(pp->pr_CurrentDir);
else {
if (*(s-1) == '/') s--;
*s = '\0';
if (!(DirLock = Lock(Dir, ACCESS_READ))) {
SimpleRequest(PCfg->ReqTitle, "Couldn't access \"%s\"", Dir);
FreeStr(n);
return FALSE;
}
}
WBArg->wa_Name = n;
WBArg->wa_Lock = DirLock;
return TRUE;
}
long GetTool(struct ParMConfig *PCfg, struct Extended_WBStartup *EWBS, long Stack)
{
struct ParMBase *ParMBase;
struct Process *pp;
struct DiskObject *DiskObject;
long IconStack = 0;
BPTR OldDir;
BOOL ToolFound = FALSE;
BOOL ProjectFound = FALSE;
BOOL Error = FALSE;
pp = (struct Process *)SysBase->ThisTask;
OldDir = pp->pr_CurrentDir;
do {
CurrentDir(EWBS->WBStartup.sm_ArgList->wa_Lock);
if (!(DiskObject = GetDiskObject(EWBS->WBStartup.sm_ArgList->wa_Name))) {
ToolFound = TRUE; /* No icon, assume tool */
}
else if (DiskObject->do_Type == WBTOOL) {
ToolFound = TRUE;
IconStack = DiskObject->do_StackSize;
}
else if (ProjectFound == FALSE && DiskObject->do_Type == WBPROJECT) {
ProjectFound = TRUE;
EWBS->WBStartup.sm_NumArgs++;
EWBS->WBStartup.sm_ArgList = EWBS->ArgArray;
if (!(MakeWBArg(PCfg, EWBS->ArgArray, DiskObject->do_DefaultTool)))
Error = TRUE;
}
else {
SimpleRequest(PCfg->ReqTitle, "No tool found!");
break;
}
if (DiskObject)
FreeDiskObject(DiskObject);
} while(!ToolFound && !Error);
CurrentDir(OldDir);
if (Stack)
EWBS->Stack = Stack;
else if (IconStack < 4000)
EWBS->Stack = PCfg->DefaultStack;
else
EWBS->Stack = IconStack;
return ToolFound;
}
struct Extended_WBStartup *MakeWBStartup(struct ParMConfig *PCfg, struct RunInfo *Command)
{
struct ParMBase *ParMBase;
struct Extended_WBStartup *EWBS;
if (!(EWBS = AllocMem(sizeof(struct Extended_WBStartup), MEMF_PUBLIC|MEMF_CLEAR)))
return NULL;
/* Allocate array for 2 args. Only one may be needed */
if (!(EWBS->ArgArray = AllocMem(2*sizeof(struct WBArg), MEMF_PUBLIC|MEMF_CLEAR))) {
WBFree(EWBS);
return NULL;
}
EWBS->ArrayLength = 2;
EWBS->WBStartup.sm_NumArgs = 1;
EWBS->WBStartup.sm_ArgList = &EWBS->ArgArray[1];
if (!MakeWBArg(PCfg, &EWBS->ArgArray[1], Command->ri_Cmd)) {
WBFree(EWBS);
return NULL;
}
if (!GetTool(PCfg, EWBS, Command->ri_Stack)) {
WBFree(EWBS);
return NULL;
}
return EWBS;
}
/* load and run a workbench program */
void WBRun(struct ParMConfig *PCfg, struct Extended_WBStartup *EWBS, BYTE Pri)
{
struct ParMBase *ParMBase;
struct Process *pp;
APTR OldPtr;
BPTR OldDir, CmdDir;
char *Cmd;
char Path[256];
OldDir = CurrentDir(CmdDir = EWBS->WBStartup.sm_ArgList->wa_Lock);
Cmd = EWBS->WBStartup.sm_ArgList->wa_Name;
PathName(CmdDir, Path, 255-32);
TackOn(Path, Cmd);
EWBS->WBStartup.sm_Message.mn_ReplyPort = &ParMBase->pb_MsgPort;
EWBS->WBStartup.sm_Message.mn_Length = sizeof(struct Extended_WBStartup);
EWBS->WBStartup.sm_Message.mn_Node.ln_Type = NT_MESSAGE;
if (EWBS->WBStartup.sm_Segment = LoadPrg(Cmd)) {
pp = (struct Process *)SysBase->ThisTask;
OldPtr = pp->pr_WindowPtr;
pp->pr_WindowPtr = NULL;
if (EWBS->WBStartup.sm_Process = CreateProc(Cmd, Pri, EWBS->WBStartup.sm_Segment, EWBS->Stack)) {
PutMsg(EWBS->WBStartup.sm_Process, (struct Message *)EWBS);
ParMBase->pb_MsgCnt++; /* keep track of unreplied startup messages */
}
else {
SimpleRequest(PCfg->ReqTitle, "Couldn't execute \"%s\"\n%s.", Path, StrIoErr());
WBFree(EWBS);
}
pp->pr_WindowPtr = OldPtr;
}
else {
SimpleRequest(PCfg->ReqTitle, "Couldn't load \"%s\"\n%s.", Path, StrIoErr());
WBFree(EWBS);
}
CurrentDir(OldDir);
}
void Command(struct ParMConfig *PCfg)
{
BPTR fh = NULL;
struct RunInfo Command;
char *Cmd, CmdBuf[CMDBUFSIZE+40];
if (PCfg->SimpleCmdMode && !(fh = Open(PCfg->CmdWindow, MODE_NEWFILE)))
return;
Command.ri_Cmd = CmdBuf;
Command.ri_Args = 0;
Command.ri_Window = PCfg->CmdWindow;
Command.ri_Stack = PCfg->DefaultStack;
Command.ri_Pri = 0;
Cmd = PCfg->CommandBuffer;
if (GetString(Cmd, "Enter Command...", NULL, 60, CMDBUFSIZE) && Cmd[0]) {
strcpy(CmdBuf, Cmd);
ParseLine(CmdBuf);
if (PCfg->SimpleCmdMode) {
Execute(CmdBuf, 0, fh);
FPrintf(fh, "
Hit return...
0 p");
Read(fh, CmdBuf, 1L);
}
else {
SPrintf(&CmdBuf[strlen(CmdBuf)], "\n%s", PCfg->WaitCmd);
Run(PCfg, &Command, TOK_SHELL);
}
}
if (PCfg->SimpleCmdMode)
Close(fh);
}